﻿using System.Collections.Generic;
using System.Linq;
using ETModel;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Options;

namespace ETHotfix {
    /// <summary>
    /// 基础实体管理组件,需继承使用
    /// </summary>
    public class BaseEntityMgrComponent<T> : Component
        where T : Entity {

        [BsonElement]
        [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
        protected readonly Dictionary<long, ObjectRef<T>> idPlayers = new Dictionary<long, ObjectRef<T>>();

        public void Awake() {
        }

        public void Add(T player) {
            this.idPlayers.Add(player.InstanceId,new ObjectRef<T>(player));
        }

        public T Get(long InstanceId) {
            this.idPlayers.TryGetValue(InstanceId, out ObjectRef<T> player);
            return player.GetObj();
        }

        /// <summary>
        /// 移除并销毁玩家及玩家下的一切信息
        /// </summary>
        /// <param name="InstanceId"></param>
		public void Remove(long InstanceId) {
            this.idPlayers.TryGetValue(InstanceId, out ObjectRef<T> player);
            this.idPlayers.Remove(InstanceId);
            player.GetObj()?.Dispose();
        }
        /// <summary>
        /// 移除但不销毁
        /// </summary>
        /// <param name="InstanceId"></param>
		public void RemoveNoDispose(long InstanceId) {
            this.idPlayers.Remove(InstanceId);
        }
        /// <summary>
        /// 移除并销毁单位
        /// </summary>
        /// <param name="ids"></param>
        public void RemoveAll(IEnumerable<long> ids) {
            foreach (var id in ids) {
                Remove(id);
            }
        }

        /// <summary>
        /// 总数
        /// </summary>
        public int Count {
            get {
                return this.idPlayers.Count;
            }
        }

        /// <summary>
        /// 获取所有
        /// </summary>
        /// <returns></returns>
        public T[] GetAll() {
            return this.idPlayers.Values.Select(p => p.GetObj()).Where(p => p != null).ToArray();
        }
        /// <summary>
        /// 获取第一个
        /// </summary>
        /// <returns></returns>
        public T GetFirst() {
            return this.idPlayers.Values.FirstOrDefault(p => p.GetObj()!=null).GetObj();
        }

        public override void Dispose() {
            if (IsDisposed) {
                return;
            }

            base.Dispose();

            foreach (var player in idPlayers.Values) {
                player.GetObj()?.Dispose();
            }
            idPlayers.Clear();

        }
    }
}